package com.yunzai.onebot.service.impl;

import com.google.gson.Gson;
import com.google.gson.JsonObject;
import com.yunzai.onebot.config.OneBotConfig;
import com.yunzai.onebot.service.IOneBotService;
import com.yunzai.onebot.websocket.OneBotClient;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;

import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

@Service
public class OneBotServiceImpl implements IOneBotService {

    private static final Log log = LogFactory.getLog(OneBotServiceImpl.class);

    private static OneBotClient client;

    private static boolean isCreateBot = false;

    @Autowired
    private OneBotConfig oneBotConfig;

    @Override
    public void sendMessage(String message) {
        if (client == null || client.isClosed()) init(message);
        if (isCreateBot) {
            // 发送消息
            send(message);
        }
    }

    @Override
    public List<JsonObject> getNewMessage(Long userId) {
        return client.getNewMessage(userId);
    }

    /**
     * 发送消息
     */
    private void send(String message) {
        //发送消息
        JsonObject json = new Gson().fromJson(message, JsonObject.class);
        json.addProperty("post_type", "message");
        json.addProperty("message_type", "private");
        json.addProperty("sub_type", "sub_type");
        long userId = json.get("user_id").getAsLong();

        saveMyMessage(userId, json.get("message").getAsString());

        client.sendMessage(json);
    }

    /**
     * 将用户发的消息返回去
     * @param userId 用户ID
     * @param message 消息内容
     */
    private void saveMyMessage(Long userId, String message) {
        JsonObject myMessage = new JsonObject();
        myMessage.addProperty("action", "my_msg");
        myMessage.addProperty("echo", UUID.randomUUID().toString());

        JsonObject params = new JsonObject();
        params.addProperty("user_id", userId);

        List<JsonObject> messageList = new ArrayList<>();
        JsonObject msg = new JsonObject();
        msg.addProperty("type", "text");

        JsonObject data = new JsonObject();
        data.addProperty("text", message);
        msg.add("data", data);
        messageList.add(msg);

        params.add("message", new Gson().toJsonTree(messageList));
        myMessage.add("params", params);
        client.addUserMessageList(userId, myMessage);
    }

    /**
     * 告诉Yunzai，机器人已经准备就绪，可以向我推送消息
     */
    private void init(String message) {
        isCreateBot = false;
        new Thread(() -> {
            while (oneBotConfig == null) {
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
            try {
                client = new OneBotClient(oneBotConfig.getUrl(), oneBotConfig.getBot());
                log.info("已创建oneBot请求对象：" + oneBotConfig.getUrl());
            } catch (URISyntaxException e) {
                throw new RuntimeException(e);
            }
            client.connect();
        }).start();
        new Thread(() -> {
            while (client == null || !client.isOpen()) {
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
            log.info("已连接oneBot服务器：" + oneBotConfig.getUrl());
            // 机器人还没上线发送上线申请
            botLogin(message);
        }).start();
    }

    /**
     * 机器人上线
     */
    private void botLogin(String message) {
        String bot = oneBotConfig.getBot();
        String master = oneBotConfig.getMaster();
        JsonObject connect = new JsonObject();
        connect.addProperty("post_type", "meta_event");
        connect.addProperty("meta_event_type", "lifecycle");
        connect.addProperty("message", "#Bot验证" + bot + ":" + master);
        connect.addProperty("user_id", bot);
        connect.addProperty("time", 0);

        JsonObject info = new JsonObject();
        info.addProperty("user_id", bot);
        info.addProperty("nickname", "流萤");
        connect.add("info",info);
//        log.info("发送Bot验证信息：" + connect);
        client.sendMessage(connect);
        connect.addProperty("message", "#Bot上线");
//        log.info("发送Bot上线申请：" + connect);
        client.sendMessage(connect);
        isCreateBot = true;
        send(message);
    }

    private static long startTime = System.currentTimeMillis();

    // 使用定时任务替代轮询（Spring Scheduler）
    @Scheduled(fixedRate = 2000)
    public void heartbeat() {
        if (isCreateBot) {
            JsonObject json = new JsonObject();
            json.addProperty("post_type", "meta_event");
            json.addProperty("meta_event_type", "heartbeat");
            json.addProperty("self_id", oneBotConfig.getBot());
            json.addProperty("user_id", oneBotConfig.getBot());
            JsonObject status = new JsonObject();
            status.addProperty("time", System.currentTimeMillis() - startTime / 1000);
            json.add("status", status);
            if (client != null && client.isOpen()) client.send(json.toString());
        }
    }

}
